home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
graphics
/
fig2mf
/
fig2MF.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-18
|
10KB
|
630 lines
/*
* fig2MF -- convert fig to mfpic METAFONT code
*
* copyright (c) 1993 Anthony Starks (ajs@merck.com)
* You may do anything you want with this code except sell it
* or claim that you wrote it.
*
* Version 0.00 -- Incorporate Tobin's small suggestions
* Version 0.01 -- Change scaling to inches,
* default [x-y]scale is 1/8 inch
* slight format changes in cinit()
* Version 0.02 -- Fixed pen switching bug
* Version 0.03 -- Support new arcthree mode
* Version 0.04 -- Token support for text
*/
#include <stdio.h>
#define put_msg(x) fputs(x, stderr); \
fprintf(stderr, \
" at line %d of file \"%s\" \n", line, curfile)
#define dofill() 1.2-((double)area_fill/(double)FILL_BLACK)
#define dopen(x) ((x-1)*PEN_INCR)+DEF_PEN
#define VERSION 0.04
#define BUF_SIZE 1024
#define O_ELLIPSE 1
#define O_POLYLINE 2
#define O_SPLINE 3
#define O_TEXT 4
#define O_ARC 5
#define O_COMP 6
#define O_ECOMP -6
#define FILL_BLACK 21
#define N_CURVE 11
#define N_POLYLINE 12
#define N_ELLIPSE 19
#define N_ARC 20
#define DEF_PEN 0.5
#define PEN_INCR 0.10
#define DEF_BFILE "graphbase.mf"
char buf[BUF_SIZE];
typedef struct {
char *keyword;
double *value;
} Options;
int line;
double ppi;
double mag;
double code;
double mfpen;
double xscale;
double yscale;
double xl;
double yl;
double xu;
double yu;
double maxy;
char *progname;
char *curfile;
char basefile[100];
Options opts[] = {
{"-mag", &mag},
{"-code", &code},
{"-pen", &mfpen},
{"-xscale", &xscale},
{"-yscale", &yscale},
{"-xneg", &xl},
{"-xpos", &xu},
{"-yneg", &yl},
{"-ypos", &yu},
{"-top", &maxy},
{NULL, NULL}
};
main(argc, argv)
int argc;
char *argv[];
{
FILE *fp;
int i;
progname = argv[0];
curfile = "Standard Input";
strcpy(basefile, DEF_BFILE);
line=1;
mag=1000.0;
code=32.0;
mfpen=0.5;
xscale=0.125;
yscale=0.125;
xl=0.0;
xu=8.0;
yl=0.0;
yu=8.0;
maxy=8.0;
if (argc < 2)
process("-");
else
{
for (i=1; i < argc; i++)
{
parse(argv[i]);
}
}
ffin();
exit(0);
}
parse(s)
char *s;
{
int i, n;
char *strchr();
double atof();
for (i=0; opts[i].keyword != NULL; i++)
{
if (strncmp(s, opts[i].keyword, strlen(opts[i].keyword)) == 0)
{
*opts[i].value = atof(strchr(s, '=')+1);
return;
}
}
process(s);
}
process(filename)
char *filename;
{
FILE *fp;
int coord_sys, object;
if (filename[0] == '-')
{
curfile = "Standard Input";
fp = stdin;
}
else
{
curfile=filename;
if ((fp = fopen(filename, "r")) == NULL)
{
fprintf(stderr,
"%s: cannot open the input file \"%s\"\n",
progname, filename);
return;
}
}
line = 1;
fgets(buf, sizeof(buf), fp);
if (strncmp(buf, "#FIG 2.1", 8) != 0)
{
put_msg("Not a fig 2.1 file");
return;
}
get_line(fp);
if (sscanf(buf, "%lf%d\n", &ppi, &coord_sys) != 2)
{
put_msg("Incomplete data");
return;
}
cinit();
while (get_line(fp) > 0)
{
if (sscanf(buf, "%d", &object) != 1)
{
put_msg("Incorrect format");
return;
}
switch(object)
{
case O_COMP:
case O_ECOMP:
break;
case O_ELLIPSE:
ellipse(fp);
break;
case O_POLYLINE:
polyline(fp);
break;
case O_SPLINE:
curve(fp);
break;
case O_TEXT:
text(fp);
break;
case O_ARC:
arc(fp);
break;
default:
fprintf(stderr, "%d is an ", object);
put_msg("unknown object");
break;
}
}
cfin();
if (fp != stdin) fclose(fp);
}
polyline(fp)
FILE *fp;
{
int c,
n,
type,
subtype,
style,
radius,
thickness,
color,
depth,
pen,
area_fill,
fa,
ba,
at,
as,
eflag;
double style_val,
athick,
awidth,
aht;
char epsfile[100];
c = 0;
n = sscanf(buf, "%d%d%d%d%d%d%d%d%lf%d%d%d",
&type,
&subtype,
&style,
&thickness,
&color,
&depth,
&pen,
&area_fill,
&style_val,
&radius,
&fa,
&ba);
if (n != N_POLYLINE)
{
put_msg("Malformed polyline");
return c;
}
if (subtype == 5) fscanf(fp, "%d%s", &eflag, epsfile);
if (fa) fscanf(fp, "%d%d%lf%lf%lf\n", &at, &as, &athick, &awidth, &aht);
if (ba) fscanf(fp, "%d%d%lf%lf%lf\n", &at, &as, &athick, &awidth, &aht);
if (thickness > 1)
printf(" pickup pencircle scaled %.2lfpt;\n",
dopen(thickness));
if (area_fill == FILL_BLACK)
printf(" cycleshade(0, false,\n");
else if (area_fill < FILL_BLACK && area_fill > 0)
printf(" cycleshade(%lfpt, false,\n", dofill());
else
printf(" curve(false, false,\n");
c = coords(type, fp);
if (thickness > 1)
printf(" pickup pencircle scaled %.2lfpt;\n",
mfpen);
return c;
}
curve(fp)
FILE *fp;
{
int n,
c,
i,
type,
style,
subtype,
thickness,
color,
depth,
pen,
area_fill,
fa,
ba,
at,
as;
double style_val,
athick,
awidth,
aht,
z;
c = 0;
n = sscanf(buf, "%d%d%d%d%d%d%d%d%lf%d%d",
&type,
&subtype,
&style,
&thickness,
&color,
&depth,
&pen,
&area_fill,
&style_val,
&fa,
&ba);
if (n != N_CURVE)
{
put_msg("Malformed spline");
return c;
}
if (fa) fscanf(fp, "%d%d%lf%lf%lf\n", &at, &as, &athick, &awidth, &aht);
if (ba) fscanf(fp, "%d%d%lf%lf%lf\n", &at, &as, &athick, &awidth, &aht);
if (thickness > 1)
printf(" pickup pencircle scaled %.2lfpt;\n",
dopen(thickness));
if (area_fill == FILL_BLACK)
printf(" cycleshade(0, true,\n");
else if (area_fill < FILL_BLACK && area_fill > 0)
printf(" cycleshade(%lfpt, true,\n", dofill());
else
printf(" curve(true, false,\n");
c = coords(type, fp);
if (subtype > 1)
for (i=0; i < c*4; i++)
fscanf(fp, "%lf", &z);
if (thickness > 1)
printf(" pickup pencircle scaled %.2lfpt;\n", mfpen);
return c;
}
coords(obj, fp)
int obj;
FILE *fp;
{
int c, n, x, y;
c = 0;
if ((n = fscanf(fp, "%d%d", &x, &y)) != 2)
{
put_msg("Incomplete object");
return c;
}
printf(" (%lf, %lf)", x/ppi, maxy-(y/ppi));
for (c = 1;;)
{
if (fscanf(fp, "%d%d", &x, &y) != 2)
{
put_msg("Incomplete object");
fputs(buf, stderr);
return c;
}
if (x == 9999) break;
printf(",\n (%lf, %lf)", x/ppi, maxy-(y/ppi));
c++;
}
printf(");\n");
return c;
}
ellipse(fp)
FILE *fp;
{
int n,
type,
subtype,
style,
thickness,
color,
depth,
pen,
area_fill,
dir,
cx,
cy,
rx,
ry,
sx,
sy,
ex,
ey;
double style_val,
angle;
n = sscanf(buf, "%d%d%d%d%d%d%d%d%lf%d%lf%d%d%d%d%d%d%d%d",
&type,
&subtype,
&style,
&thickness,
&color,
&depth,
&pen,
&area_fill,
&style_val,
&dir,
&angle,
&cx,
&cy,
&rx,
&ry,
&sx,
&sy,
&ex,
&ey);
if (n != N_ELLIPSE)
{
put_msg("Malformed circle or ellipse");
return;
}
if (thickness > 1)
printf(" pickup pencircle scaled %.2lfpt;\n",
dopen(thickness));
if (subtype == 3 || subtype == 4)
{
if (area_fill == FILL_BLACK)
printf(" circshade(0, ");
else if (area_fill < FILL_BLACK && area_fill > 0)
printf(" circshade(%lfpt, ", dofill());
else
printf(" circle(");
printf("(%lf,%lf),%lf);\n",
cx/ppi, maxy-(cy/ppi), rx/ppi);
}
else if (subtype == 1 || subtype == 2)
{
if (area_fill == FILL_BLACK)
printf(" ellshade(0, ");
else if (area_fill < FILL_BLACK && area_fill > 0)
printf(" ellshade(%lfpt, ", dofill());
else
printf(" ellipse(");
printf("(%lf,%lf),%lf,%lf,0);\n",
cx/ppi, maxy-(cy/ppi), rx/ppi, ry/ppi);
}
if (thickness > 1)
printf(" pickup pencircle scaled %.2lfpt;\n", mfpen);
}
arc(fp)
FILE *fp;
{
int n,
type,
subtype,
style,
thickness,
color,
depth,
pen,
fill,
dir,
fa,
ba,
x1,
y1,
x2,
y2,
x3,
y3;
double style_val,
cx,
cy;
n = sscanf(buf, "%d%d%d%d%d%d%d%d%lf%d%d%d%lf%lf%d%d%d%d%d%d",
&type,
&subtype,
&style,
&thickness,
&color,
&depth,
&pen,
&fill,
&style_val,
&dir,
&fa,
&ba,
&cx,
&cy,
&x1,
&y1,
&x2,
&y2,
&x3,
&y3);
if (fa) get_line(fp);
if (ba) get_line(fp);
if (n != N_ARC)
{
put_msg("Malformed arc");
return n;
}
if (thickness > 1)
printf(" pickup pencircle scaled %.2lfpt;\n",
dopen(thickness));
printf(" arcthree((%lf,%lf), (%lf,%lf), (%lf,%lf));\n",
x1/ppi,
maxy-(y1/ppi),
x2/ppi,
maxy-(y2/ppi),
x3/ppi,
maxy-(y3/ppi));
if (thickness > 1)
printf(" pickup pencircle scaled %.2lfpt;\n",
mfpen);
return n;
}
text(fp)
FILE *fp;
{
int n,
x,
y;
int type,
font,
size,
pen,
color,
depth,
filler,
angle,
flags,
ht,
len;
char text[80],
junk[2],
*p,
*strrchr();
n = sscanf(buf, "%*d%d%d%d%d%d%d%lf%d%d%d%d%d%[^\1]%[\1]",
&type,
&font,
&size,
&pen,
&color,
&depth,
&angle,
&flags,
&ht,
&len,
&x,
&y,
text,
junk);
if ((n != 13) && (n != 14))
{
put_msg("Bad Text");
return 0;
}
p = &text[1];
printf("%% label((%lf,%lf),%s)\n", x/ppi, maxy-(y/ppi), p);
return(strlen(text));
}
cinit()
{
static int once = 0;
static int curchar;
if (++once == 1)
{
curchar = (int)code;
printf("%%\n%% %s version %.2lf --- Preamble\n%%\n",
progname, VERSION);
printf("mag:=%g/1000; input %s; code:=%g;\n",
mag, basefile, code);
printf("mfpicenv;\ninterim hdwdr:=1; interim hdten:=1;\n");
printf("interim penwd:=%.2lfpt;\npickup pencircle scaled penwd;\n", mfpen);
}
printf("%%\n%% %s (char %d)\n%%\n", curfile, ++curchar);
printf("xscale:=%.3lf; yscale:=%.3lf; bounds(%.3lf,%.3lf,%.3lf,%.3lf);\n",
xscale, yscale, xl, xu, yl, yu);
printf("beginchar(incr code,xscale*(xpos-xneg)*in#,yscale*(ypos-yneg)*in#,0);\n");
printf(" setztr;\n");
printf(" pickup pencircle scaled %.2lfpt;\n", mfpen);
}
cfin()
{
printf("endchar;\n");
}
ffin()
{
if (line > 1) printf("endmfpicenv;\nend.\n");
}
get_line(fp)
FILE *fp;
{
while (1)
{
if (NULL == fgets(buf, BUF_SIZE, fp))
{
return (-1);
}
line++;
if (*buf != '\n' && *buf != '#')
return (1);
/* Skip empty and comment lines */
}
}